#include <iostream>

template<int object_size,int object_num = 20>
class MemPool{
public:
    MemPool(){
        this->freeNodeHeader = nullptr;
        this->memBlockHeader = nullptr;
    }

    ~MemPool(){
        MemBlock* ptr;
        while(memBlockHeader != nullptr){
            ptr = memBlockHeader->pNext;
            delete memBlockHeader;
            memBlockHeader = ptr;
        }
    }

public:
    //申请空闲节点
    void* malloc();
    //释放已分配的节点
    void free(void*);

private:

    //空闲节点结构体
    struct FreeNode{
        FreeNode* pNext;
        char data[object_size];
        FreeNode() : pNext(nullptr){}
    };
    //内存块结构体
    struct MemBlock{
        MemBlock* pNext;
        FreeNode data[object_num];
        MemBlock() : pNext(nullptr){}
    };

    FreeNode* freeNodeHeader;
    MemBlock* memBlockHeader;
};

template <int object_size, int object_num>
void *MemPool<object_size, object_num>::malloc()
{
    if(freeNodeHeader == nullptr){
        MemBlock* newBlock = new MemBlock;
        freeNodeHeader = &newBlock->data[0];
        for(int i = 1;i < object_num;i++){
            newBlock->data[i-1].pNext = &newBlock->data[i];
        }
        //如果是首次申请内存块需要将内存块加入到内存块链表
        if(memBlockHeader == nullptr){
            memBlockHeader = newBlock;
        }else{
            newBlock->pNext = memBlockHeader;
            memBlockHeader = newBlock;
        }
    }
    //返回头节点
    void* firstfreenode = freeNodeHeader;
    freeNodeHeader = freeNodeHeader->pNext;
    return firstfreenode;
}

template <int object_size, int object_num>
void MemPool<object_size, object_num>::free(void *p)
{
    FreeNode* pNode = (FreeNode*)p;
    pNode->pNext = freeNodeHeader;//释放的空间加到头部
    freeNodeHeader = pNode;
}

class ActualClass{
    static int count;
    int No;
public:
    ActualClass(){
        No = count;
        count++;
    }
    void print(){
        std::cout<<this<<": ";
        std::cout<<"the "<<No<<"th object"<<std::endl;
    }

    void* operator new(size_t size);
    void operator delete(void* p);
};

//定义内存池对象
MemPool<sizeof(ActualClass),2> mp;

void *ActualClass::operator new(size_t size)
{
    return mp.malloc();
}

void ActualClass::operator delete(void *p)
{
    mp.free(p);
}

int ActualClass::count = 0;

int main(){
	ActualClass* p1 = new ActualClass;
	p1->print();

	ActualClass* p2 = new ActualClass;
	p2->print();
	delete p1;

	p1 = new ActualClass;
	p1->print();

	ActualClass* p3 = new ActualClass;
	p3->print();

	delete p1;
	delete p2;
	delete p3;
    
    return 0;
}
